﻿using System;
using System.NETool;
using System.Threading;

namespace Sunny.FrameDecoder.Demo
{
    internal class TestByteFrameDecoder
    {
        /// <summary>
        /// 测试固定长度解码器
        /// </summary>
        public static void TestFixedLengthFrameDecoder()
        {
            Console.WriteLine(Environment.NewLine + "TestFixedLengthFrameDecoder:");
            FixedLengthFrameDecoder decoder = new FixedLengthFrameDecoder(5);
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 1, 2, 3 });
            decoder.Decode(new byte[] { 4, 5, 1, 2 });
            decoder.Decode(new byte[] { 3, 4, 6, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 7, 1, 2 });
            decoder.Decode(new byte[] { 3, 4, 8, 1, 2 });
            decoder.Decode(new byte[] { 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 1, 2, 3, 4, 9 });
        }

        /// <summary>
        /// 测试分隔符(尾部分隔符)解码器
        /// </summary>
        public static void TestDelimiterBasedFrameDecoder()
        {
            Console.WriteLine(Environment.NewLine + "TestDelimiterBasedFrameDecoder:");
            DelimiterBasedFrameDecoder decoder = new DelimiterBasedFrameDecoder(new byte[] { 0xAA });
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3 });
            decoder.Decode(new byte[] { 4, 5, 0xAA, 1, 2 });
            decoder.Decode(new byte[] { 3, 4, 5, 0xAA, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3, 4, 5, 0xAA });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xAA });
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3, 4, 5, 0xAA, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3, 4, 5, 0xAA });
        }

        /// <summary>
        /// 测试头部分隔符解码器
        /// </summary>
        public static void TestHeaderDelimiterFrameDecoder()
        {
            Console.WriteLine(Environment.NewLine + "TestHeaderDelimiterFrameDecoder:");
            HeaderDelimiterFrameDecoder decoder = new HeaderDelimiterFrameDecoder(new byte[] { 0xAA });
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 1, 2, 3, 0xAA, 1, 2, 3 });
            decoder.Decode(new byte[] { 4, 5, 0xAA, 1, 2 });
            decoder.Decode(new byte[] { 3, 4, 5, 0xAA, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3, 4, 5, 0xAA });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xAA });
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3, 4, 5, 0xAA, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xAA, 1, 2, 3, 4, 5, 0xAA });
        }

        /// <summary>
        /// 测试头部尾部分隔符解码器
        /// </summary>
        public static void TestHeaderTailFrameDecoder()
        {
            Console.WriteLine(Environment.NewLine + "TestHeaderTailFrameDecoder:");
            HeaderTailFrameDecoder decoder = new HeaderTailFrameDecoder(new byte[] { 0xAA }, new byte[] { 0xBB });
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder; ;
            decoder.Decode(new byte[] { 3, 4, 5, 0xAA, 1, 2, 3 });
            decoder.Decode(new byte[] { 4, 5, 0xBB, 1, 0xAA, 1, 2 });
            decoder.Decode(new byte[] { 3, 4, 5, 0xBB, 1, 2, 0xAA, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 1, 2, 3, 4, 5, 0xBB, 0xAA, 0xAA, });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xBB });
            decoder.Decode(new byte[] { 0xAA, 0xBB });
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3, 4, 5, 0xBB, 0xAA, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xAA, 1, 2, 3, 4, 5, 0xBB });
        }

        /// <summary>
        /// 测试LengthValue解码器
        /// </summary>
        public static void TestLengthValueFrameDecoder()
        {
            Console.WriteLine(Environment.NewLine + "TestLengthValueFrameDecoder:");
            LengthValueFrameDecoder decoder = new LengthValueFrameDecoder(LengthType.Byte);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 3, 1, 2, 3, 1, 1, 0 });
            decoder.Decode(new byte[] { 4, 1, 2, 3, 4, 5, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 2, 1, 2, 5, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 5, 1, 2, 3, 4, 5, 1, 1, 0, 5 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 3 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 5, 1, 2, 3, 4, 5, 5, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 5, 1, 2, 3, 4, 5 });

            Console.WriteLine(Environment.NewLine + "TestLengthValueFrameDecoder:");
            decoder = new LengthValueFrameDecoder(LengthType.Byte, true, true);
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 4, 1, 2, 3, 2, 1, 1 });
            decoder.Decode(new byte[] { 5, 1, 2, 3, 4, 6, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 3, 1, 2, 6, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 6, 1, 2, 3, 4, 5, 2, 1, 1, 6 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 4 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 6, 1, 2, 3, 4, 5 });
        }

        /// <summary>
        /// 测试TagLengthValue解码器
        /// </summary>
        public static void TestTagLengthValueFrameDecoder()
        {
            Console.WriteLine(Environment.NewLine + "TestTagLengthValueFrameDecoder:");
            TagLengthValueFrameDecoder decoder = new TagLengthValueFrameDecoder(1, LengthType.Byte);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 0xA3, 3, 1, 2, 3, 0xA1, 1, 1, 0xA0, 0 });
            decoder.Decode(new byte[] { 0xA4, 4, 1, 2, 3, 4, 0xA5, 5, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 0xA2, 2, 1, 2, 0xA5, 5, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xA5, 5, 1, 2, 3, 4, 5, 0xA1, 1, 1, 0xA0, 0, 0xA5, 5 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xA3, 3 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 0xA5, 5, 1, 2, 3, 4, 5, 0xA5, 5, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xA5, 5, 1, 2, 3, 4, 5 });

            Console.WriteLine(Environment.NewLine + "TestTagLengthValueFrameDecoder: isFullLength = true");
            decoder = new TagLengthValueFrameDecoder(1, LengthType.Byte, true, true);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 0xA3, 5, 1, 2, 3, 0xA1, 3, 1, 0xA0, 2 });
            decoder.Decode(new byte[] { 0xA4, 6, 1, 2, 3, 4, 0xA5, 7, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 0xA2, 4, 1, 2, 0xA5, 7, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xA5, 7, 1, 2, 3, 4, 5, 0xA1, 3, 1, 0xA0, 2, 0xA5, 7 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xA3, 5 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 0xA5, 7, 1, 2, 3, 4, 5, 0xA5, 7, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xA5, 7, 1, 2, 3, 4, 5 });

            Console.WriteLine(Environment.NewLine + "TestTagLengthValueFrameDecoder: tagLength = 0");
            decoder = new TagLengthValueFrameDecoder(0, LengthType.Byte);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 3, 1, 2, 3, 1, 1, 0 });
            decoder.Decode(new byte[] { 4, 1, 2, 3, 4, 5, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 2, 1, 2, 5, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 5, 1, 2, 3, 4, 5, 1, 1, 0, 5 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 3 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 5, 1, 2, 3, 4, 5, 5, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 5, 1, 2, 3, 4, 5 });
        }

        /// <summary>
        /// 测试TagLengthValue解码器
        /// </summary>
        public static void TestHeaderTagLengthValueTailFrameDecoder()
        {
            Console.WriteLine(Environment.NewLine + "TestHeaderTagLengthValueTailFrameDecoder:");
            HeaderTagLengthValueTailFrameDecoder decoder = new HeaderTagLengthValueTailFrameDecoder(new byte[] { 0xAA }, new byte[] { 0xBB }, 1, LengthType.Byte);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 0xAA, 0xA3, 3, 1, 2, 3, 0xBB, 0xAA, 0xA1, 1, 1, 0xBB, 0xAA, 0xA0, 0 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 0xA4, 4, 1, 2, 3, 4, 0xBB, 0xAA, 0xA5, 5, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 0xBB, 0xAA, 0xA2, 2, 1, 2, 0xBB, 0xAA, 0xA5, 5, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 0xA5, 5, 1, 2, 3, 4, 5, 0xBB, 0xAA, 0xA1, 1, 1, 0xBB, 0xAA, 0xA0, 0, 0xBB, 0xAA, 0xA5, 5 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xBB, 0xAA, 0xA3, 3 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 0xBB, 0xAA, 0xA5, 5, 1, 2, 3, 4, 5, 0xBB, 0xAA, 0xA5, 5, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xAA, 0xA5, 5, 1, 2, 3, 4, 5, 0xBB });

            Console.WriteLine(Environment.NewLine + "TestHeaderTagLengthValueTailFrameDecoder: isFullLength = true");
            decoder = new HeaderTagLengthValueTailFrameDecoder(new byte[] { 0xAA }, new byte[] { 0xBB }, 1, LengthType.Byte, true, true);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 0xAA, 0xA3, 7, 1, 2, 3, 0xBB, 0xAA, 0xA1, 5, 1, 0xBB, 0xAA, 0xA0, 4 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 0xA4, 8, 1, 2, 3, 4, 0xBB, 0xAA, 0xA5, 9, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 0xBB, 0xAA, 0xA2, 6, 1, 2, 0xBB, 0xAA, 0xA5, 9, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 0xA5, 9, 1, 2, 3, 4, 5, 0xBB, 0xAA, 0xA1, 5, 1, 0xBB, 0xAA, 0xA0, 4, 0xBB, 0xAA, 0xA5, 9 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xBB, 0xAA, 0xA3, 7 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 0xBB, 0xAA, 0xA5, 9, 1, 2, 3, 4, 5, 0xBB, 0xAA, 0xA5, 9, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xAA, 0xA5, 9, 1, 2, 3, 4, 5, 0xBB });

            Console.WriteLine(Environment.NewLine + "TestHeaderTagLengthValueTailFrameDecoder: tagLength = 0");
            decoder = new HeaderTagLengthValueTailFrameDecoder(new byte[] { 0xAA }, new byte[] { 0xBB }, 0, LengthType.Byte);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 0xAA, 3, 1, 2, 3, 0xBB, 0xAA, 1, 1, 0xBB, 0xAA, 0 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 4, 1, 2, 3, 4, 0xBB, 0xAA, 5, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 0xBB, 0xAA, 2, 1, 2, 0xBB, 0xAA, 5, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 5, 1, 2, 3, 4, 5, 0xBB, 0xAA, 1, 1, 0xBB, 0xAA, 0, 0xBB, 0xAA, 5 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xBB, 0xAA, 3 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 0xBB, 0xAA, 5, 1, 2, 3, 4, 5, 0xBB, 0xAA, 5, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xAA, 5, 1, 2, 3, 4, 5, 0xBB });

            Console.WriteLine(Environment.NewLine + "TestHeaderTagLengthValueTailFrameDecoder: isFullLength = true，tagLength = 0");
            decoder = new HeaderTagLengthValueTailFrameDecoder(new byte[] { 0xAA }, new byte[] { 0xBB }, 0, LengthType.Byte, true, true);
            //decoder.CacheTimeout = 0;
            decoder.OnDecoder += Decoder_OnByteFrameDecoder;
            decoder.Decode(new byte[] { 0xAA, 6, 1, 2, 3, 0xBB, 0xAA, 4, 1, 0xBB, 0xAA, 3 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 7, 1, 2, 3, 4, 0xBB, 0xAA, 8, 1 });
            decoder.Decode(new byte[] { 2, 3, 4, 5, 0xBB, 0xAA, 5, 1, 2, 0xBB, 0xAA, 8, 1, 2, 3, 4, 5 });
            decoder.Decode(new byte[] { 0xBB, 0xAA, 8, 1, 2, 3, 4, 5, 0xBB, 0xAA, 4, 1, 0xBB, 0xAA, 3, 0xBB, 0xAA, 8 });
            decoder.Decode(new byte[] { 1, 2, 3, 4, 5, 0xBB, 0xAA, 6 });
            decoder.Decode(new byte[] { 1, 2 });
            decoder.Decode(new byte[] { 3, 0xBB, 0xAA, 8, 1, 2, 3, 4, 5, 0xBB, 0xAA, 8, 1, 2, 3 });
            Thread.Sleep(1000);
            decoder.Decode(new byte[] { 0xAA, 8, 1, 2, 3, 4, 5, 0xBB });
        }

        private static void Decoder_OnByteFrameDecoder(object sender, ByteFrameEventArgs e)
        {
            if (e.Decoder is HeaderTagLengthValueTailFrameDecoder htlvtfd)
            {
                TagLengthByteFrameParams p = (TagLengthByteFrameParams)e.Params;
                Console.WriteLine(p.Tag.ToHexString() + ": " + p.Length + ": " + e.Value.ToHexString() + ", " + e.Body.ToHexString());
                var frame = htlvtfd.DecodeFrame(e.Body);
                ThrowHelper.ThrowIfNull(frame);
                ThrowHelper.ThrowIfNotEquel(frame.Value, e.Value);
            }

            if (e.Decoder is TagLengthValueFrameDecoder tlvfd)
            {
                TagLengthByteFrameParams p = (TagLengthByteFrameParams)e.Params;
                Console.WriteLine(p.Tag.ToHexString() + ": " + p.Length + ": " + e.Value.ToHexString() + ", " + e.Body.ToHexString());
                var frame = tlvfd.DecodeFrame(e.Body);
                ThrowHelper.ThrowIfNull(frame);
                ThrowHelper.ThrowIfNotEquel(frame.Value, e.Value);
            }

            if (e.Decoder is LengthValueFrameDecoder lvfd)
            {
                LengthByteFrameParams p = (LengthByteFrameParams)e.Params;
                Console.WriteLine(p.Length + ": " + e.Value.ToHexString() + ", " + e.Body.ToHexString());
                var frame = lvfd.DecodeFrame(e.Body);
                ThrowHelper.ThrowIfNull(frame);
                ThrowHelper.ThrowIfNotEquel(frame.Value, e.Value);
            }

            if (e.Decoder is FixedLengthFrameDecoder flfd)
            {
                Console.WriteLine(e.Value.ToHexString());
                ThrowHelper.ThrowIfNotEquel(e.Value.Length == flfd.FrameLength);
            }

            if (e.Decoder is DelimiterBasedFrameDecoder dbfd)
            {
                Console.WriteLine(e.Value.ToHexString() + ", " + e.Body.ToHexString());
                var frame = dbfd.DecodeFrame(e.Body);
                ThrowHelper.ThrowIfNull(frame);
                ThrowHelper.ThrowIfNotEquel(frame.Value, e.Value);
            }

            if (e.Decoder is HeaderDelimiterFrameDecoder hdfd)
            {
                Console.WriteLine(e.Value.ToHexString() + ", " + e.Body.ToHexString());
                var frame = hdfd.DecodeFrame(e.Body);
                ThrowHelper.ThrowIfNull(frame);
                ThrowHelper.ThrowIfNotEquel(frame.Value, e.Value);
            }

            if (e.Decoder is HeaderTailFrameDecoder htfd)
            {
                Console.WriteLine(e.Value.ToHexString() + ", " + e.Body.ToHexString());
                var frame = htfd.DecodeFrame(e.Body);
                ThrowHelper.ThrowIfNull(frame);
                ThrowHelper.ThrowIfNotEquel(frame.Value, e.Value);
            }
        }

        public static void TestCreateFrame()
        {
            byte[] bts = new byte[] { 1, 2, 3, 0xFF, 0xFB };
            DelimiterBasedFrameDecoder decoder1 = new DelimiterBasedFrameDecoder(new byte[] { 0xFF, 0xFB });
            decoder1.OnDecoder += DelimiterBasedFrameDecoder_OnDecoder;
            decoder1.Decode(bts);

            bts = new byte[] { 0xFF, 0xFB, 1, 2, 3 };
            HeaderDelimiterFrameDecoder decoder2 = new HeaderDelimiterFrameDecoder(new byte[] { 0xFF, 0xFB });
            decoder2.OnDecoder += DelimiterBasedFrameDecoder_OnDecoder;
            decoder2.Decode(bts);
            decoder2.Decode(bts);

            bts = new byte[] { 0xFF, 0xFB, 0xAA, 2, 3, 4, 0xF7, 0xF7 };
            HeaderTagLengthValueTailFrameDecoder decoder3 = new HeaderTagLengthValueTailFrameDecoder(new byte[] { 0xFF, 0xFB }, new byte[] { 0xF7, 0xF7 }, 1, LengthType.Byte);
            decoder3.OnDecoder += DelimiterBasedFrameDecoder_OnDecoder;
            decoder3.Decode(bts);

            bts = new byte[] { 0xFF, 0xFB, 0xAA, 2, 3, 4, 0xF7, 0xF7 };
            HeaderTailFrameDecoder decoder4 = new HeaderTailFrameDecoder(new byte[] { 0xFF, 0xFB }, new byte[] { 0xF7, 0xF7 });
            decoder4.OnDecoder += DelimiterBasedFrameDecoder_OnDecoder;
            decoder4.Decode(bts);

            bts = new byte[] { 2, 3, 4 };
            LengthValueFrameDecoder decoder5 = new LengthValueFrameDecoder(LengthType.Byte);
            decoder5.OnDecoder += DelimiterBasedFrameDecoder_OnDecoder;
            decoder5.Decode(bts);

            bts = new byte[] { 0xAA, 2, 3, 4 };
            TagLengthValueFrameDecoder decoder6 = new TagLengthValueFrameDecoder(1, LengthType.Byte);
            decoder6.OnDecoder += DelimiterBasedFrameDecoder_OnDecoder;
            decoder6.Decode(bts);
        }

        private static void DelimiterBasedFrameDecoder_OnDecoder(object sender, ByteFrameEventArgs e)
        {
            if (e.Decoder is TagLengthValueFrameDecoder)
            {
                byte[] bts = new byte[] { 0xAA, 2, 3, 4 };
                TagLengthValueFrameDecoder decoder = (TagLengthValueFrameDecoder)e.Decoder;
                TagLengthByteFrameParams args = (TagLengthByteFrameParams)e.Params;
                Console.WriteLine("TagLengthValueFrameDecoder: " + decoder.CreateFrame(args.Tag, e.Value).AsSpan().SequenceEqual(bts.AsSpan()));
            }

            if (e.Decoder is LengthValueFrameDecoder)
            {
                byte[] bts = new byte[] { 2, 3, 4 };
                LengthValueFrameDecoder decoder = (LengthValueFrameDecoder)e.Decoder;
                Console.WriteLine("LengthValueFrameDecoder: " + decoder.CreateFrame(e.Value).AsSpan().SequenceEqual(bts.AsSpan()));
            }

            if (e.Decoder is HeaderTailFrameDecoder)
            {
                byte[] bts = new byte[] { 0xFF, 0xFB, 0xAA, 2, 3, 4, 0xF7, 0xF7 };
                HeaderTailFrameDecoder decoder = (HeaderTailFrameDecoder)e.Decoder;
                Console.WriteLine("HeaderTailFrameDecoder: " + decoder.CreateFrame(e.Value).AsSpan().SequenceEqual(bts.AsSpan()));
            }

            if (e.Decoder is HeaderTagLengthValueTailFrameDecoder)
            {
                byte[] bts = new byte[] { 0xFF, 0xFB, 0xAA, 2, 3, 4, 0xF7, 0xF7 };
                HeaderTagLengthValueTailFrameDecoder decoder = (HeaderTagLengthValueTailFrameDecoder)e.Decoder;
                TagLengthByteFrameParams args = (TagLengthByteFrameParams)e.Params;
                Console.WriteLine("HeaderTagLengthValueTailFrameDecoder: " + decoder.CreateFrame(args.Tag, e.Value).AsSpan().SequenceEqual(bts.AsSpan()));
            }

            if (e.Decoder is DelimiterBasedFrameDecoder)
            {
                byte[] bts = new byte[5] { 1, 2, 3, 0xFF, 0xFB };
                DelimiterBasedFrameDecoder decoder = (DelimiterBasedFrameDecoder)e.Decoder;
                Console.WriteLine("DelimiterBasedFrameDecoder: " + decoder.CreateFrame(e.Value).AsSpan().SequenceEqual(bts.AsSpan()));
            }

            if (e.Decoder is HeaderDelimiterFrameDecoder)
            {
                byte[] bts = new byte[5] { 0xFF, 0xFB, 1, 2, 3 };
                HeaderDelimiterFrameDecoder decoder = (HeaderDelimiterFrameDecoder)e.Decoder;
                Console.WriteLine("HeaderDelimiterFrameDecoder: " + decoder.CreateFrame(e.Value).AsSpan().SequenceEqual(bts.AsSpan()));
            }
        }
    }
}
